package com.idig8.test;

import com.idig8.bean.*;
import com.idig8.service.UserService;
import org.drools.core.base.RuleNameEqualsAgendaFilter;
import org.drools.core.base.RuleNameStartsWithAgendaFilter;
import org.drools.core.io.impl.UrlResource;
import org.junit.Test;
import org.kie.api.KieServices;
import org.kie.api.builder.KieModule;
import org.kie.api.builder.KieRepository;
import org.kie.api.io.Resource;
import org.kie.api.runtime.KieContainer;
import org.kie.api.runtime.KieSession;
import org.kie.api.runtime.rule.QueryResults;
import org.kie.api.runtime.rule.QueryResultsRow;

import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.util.ArrayList;
import java.util.List;

public class DroolsTest1 {

    @Test
    public void test1(){
        KieServices kieServices = KieServices.Factory.get();
        KieContainer kieClasspathContainer = kieServices.getKieClasspathContainer();
        //会话对象，用于和规则引擎交互，因为配置文件中，设置了默认所以不需要名称直接就可以找到对应的默认的session
        KieSession kieSession = kieClasspathContainer.newKieSession();

        //构造订单对象，设置原始价格，由规则引擎根据优惠规则计算优惠后的价格
        Attendance attendance = new Attendance();
        attendance.setBaseicSalary(8000);
        attendance.setLateTime(1);

        //将数据提供给规则引擎，规则引擎会根据提供的数据进行规则匹配
        kieSession.insert(attendance);

        //激活规则引擎，如果规则匹配成功则执行规则
        kieSession.fireAllRules();
        //关闭会话
        kieSession.dispose();

        System.out.println("原来的工资：" + attendance.getBaseicSalary() +
                "，迟到扣了多少：" + attendance.getFinalSalary());
    }

    @Test
    public void test3(){
        KieServices kieServices = KieServices.Factory.get();
        KieContainer kieClasspathContainer = kieServices.getKieClasspathContainer();
        KieSession kieSession = kieClasspathContainer.newKieSession();

        ComparisonOperator Entity = new ComparisonOperator();
        Entity.setNames("张三");
        List<String> list = new ArrayList<String>();
        list.add("张三");
        list.add("李四");
        Entity.setList(list);

        //将数据提供给规则引擎，规则引擎会根据提供的数据进行规则匹配，如果规则匹配成功则执行规则
        kieSession.insert(Entity);

        kieSession.fireAllRules();
        kieSession.dispose();
    }

    @Test
    public void test4(){
        KieServices kieServices = KieServices.Factory.get();
        KieContainer kieClasspathContainer = kieServices.getKieClasspathContainer();

        KieSession kieSession = kieClasspathContainer.newKieSession();

        ComparisonOperator Entity = new ComparisonOperator();
        Entity.setNames("张三");
        List<String> list = new ArrayList<String>();
        list.add("张三");
        list.add("李四");
        Entity.setList(list);

        //将数据提供给规则引擎，规则引擎会根据提供的数据进行规则匹配，如果规则匹配成功则执行规则
        kieSession.insert(Entity);

        ////通过规则过滤器实现只执行指定规则
        kieSession.fireAllRules(new RuleNameEqualsAgendaFilter("rule_comparison_memberOf"));
        kieSession.dispose();
    }

    @Test
    public void test5() {
        KieServices kieServices = KieServices.Factory.get();
        KieContainer kieClasspathContainer = kieServices.getKieClasspathContainer();
        KieSession kieSession = kieClasspathContainer.newKieSession();


        Student student = new Student();
        student.setAge(50);

    //将数据提供给规则引擎，规则引擎会根据提供的数据进行规则匹配，如果规则匹配成功则执行规则
        kieSession.insert(student);

        kieSession.fireAllRules();
        kieSession.dispose();
    }

    @Test
    public void test6() {
        KieServices kieServices = KieServices.Factory.get();
        KieContainer kieClasspathContainer = kieServices.getKieClasspathContainer();

        KieSession kieSession = kieClasspathContainer.newKieSession();

        Teacher teacher = new Teacher();
        teacher.setAge(10);

//将数据提供给规则引擎，规则引擎会根据提供的数据进行规则匹配，如果规则匹配成功则执行规则
        kieSession.insert(teacher);

        kieSession.fireAllRules();
        kieSession.dispose();
    }

    @Test
    public void test7() {
        KieServices kieServices = KieServices.Factory.get();
        KieContainer kieClasspathContainer = kieServices.getKieClasspathContainer();
        KieSession kieSession = kieClasspathContainer.newKieSession();

        Girl girl = new Girl();
        girl.setAge(10);

//将数据提供给规则引擎，规则引擎会根据提供的数据进行规则匹配，如果规则匹配成功则执行规则
        kieSession.insert(girl);

        kieSession.fireAllRules();
        kieSession.dispose();
    }

    @Test
    public void test8() {
        KieServices kieServices = KieServices.Factory.get();
        KieContainer kieClasspathContainer = kieServices.getKieClasspathContainer();
        KieSession kieSession = kieClasspathContainer.newKieSession();

        Girl girl = new Girl();
        girl.setAge(10);

//将数据提供给规则引擎，规则引擎会根据提供的数据进行规则匹配，如果规则匹配成功则执行规则
        kieSession.insert(girl);

        kieSession.fireAllRules();
        kieSession.dispose();
    }

    @Test
    public void test9() {
        KieServices kieServices = KieServices.Factory.get();
        KieContainer kieClasspathContainer = kieServices.getKieClasspathContainer();
        KieSession kieSession = kieClasspathContainer.newKieSession();

//设置焦点，对应agenda-group分组中的规则才可能被触发
        kieSession.getAgenda().getAgendaGroup("myagendagroup_1").setFocus();

        kieSession.fireAllRules();
        kieSession.dispose();
    }

    @Test
    public void test10() {
        KieServices kieServices = KieServices.Factory.get();
        KieContainer kieClasspathContainer = kieServices.getKieClasspathContainer();
        KieSession kieSession = kieClasspathContainer.newKieSession();


        kieSession.fireAllRules();
        kieSession.dispose();
    }

    @Test
    public void test11() throws InterruptedException {
        KieServices kieServices = KieServices.Factory.get();
        KieContainer kieClasspathContainer = kieServices.getKieClasspathContainer();
        final KieSession kieSession = kieClasspathContainer.newKieSession();

        new Thread(new Runnable() {
            public void run() {
                //启动规则引擎进行规则匹配，直到调用halt方法才结束规则引擎
                kieSession.fireUntilHalt();
            }
        }).start();
        Thread.sleep(10000);
        //结束规则引擎
        kieSession.halt();
        kieSession.dispose();
    }

    @Test
    public void test12() throws InterruptedException {
        //设置日期格式,导致上面的测试类无法运行，需要也加入这个日期格式的设置。
        System.setProperty("drools.dateformat","yyyy-MM-dd HH:mm");
        KieServices kieServices = KieServices.Factory.get();
        KieContainer kieClasspathContainer = kieServices.getKieClasspathContainer();
        KieSession kieSession = kieClasspathContainer.newKieSession();
        kieSession.fireAllRules();
        kieSession.dispose();
    }

    @Test
    public void test13() {
        System.setProperty("drools.dateformat","yyyy-MM-dd HH:mm");
        KieServices kieServices = KieServices.Factory.get();
        KieContainer kieClasspathContainer = kieServices.getKieClasspathContainer();
        KieSession kieSession = kieClasspathContainer.newKieSession();

        //设置全局变量，名称和类型必须和规则文件中定义的全局变量名称对应
        kieSession.setGlobal("count",5);

        kieSession.fireAllRules();
        kieSession.dispose();

    }

    @Test
    public void test14() {
        System.setProperty("drools.dateformat","yyyy-MM-dd HH:mm");
        KieServices kieServices = KieServices.Factory.get();
        KieContainer kieClasspathContainer = kieServices.getKieClasspathContainer();
        KieSession kieSession = kieClasspathContainer.newKieSession();
        kieSession.setGlobal("count",5);
        //设置全局变量，名称和类型必须和规则文件中定义的全局变量名称对应
        List list = new ArrayList();//size为0
        kieSession.setGlobal("gList",list);

        kieSession.fireAllRules();
        kieSession.dispose();
        //因为在规则中为全局变量添加了两个元素，所以现在的size为2
        System.out.println(list.size());

    }

    @Test
    public void test15() {
        System.setProperty("drools.dateformat","yyyy-MM-dd HH:mm");
        KieServices kieServices = KieServices.Factory.get();
        KieContainer kieClasspathContainer = kieServices.getKieClasspathContainer();
        KieSession kieSession = kieClasspathContainer.newKieSession();
        kieSession.setGlobal("count",5);
        //设置全局变量，名称和类型必须和规则文件中定义的全局变量名称对应
        List list = new ArrayList();//size为0
        kieSession.setGlobal("gList",list);
        kieSession.setGlobal("userService",new UserService());

        kieSession.fireAllRules();

        kieSession.dispose();
    }

    @Test
    public void test16() {
        System.setProperty("drools.dateformat","yyyy-MM-dd HH:mm");
        KieServices kieServices = KieServices.Factory.get();
        KieContainer kieClasspathContainer = kieServices.getKieClasspathContainer();
        KieSession kieSession = kieClasspathContainer.newKieSession();
        kieSession.setGlobal("count",5);
        //设置全局变量，名称和类型必须和规则文件中定义的全局变量名称对应
        List list = new ArrayList();//size为0
        kieSession.setGlobal("gList",list);
        kieSession.setGlobal("userService",new UserService());

//        kieSession.fireAllRules();
        // 指定某种规则开头的规则名称
        kieSession.fireAllRules(new RuleNameStartsWithAgendaFilter("rule_global"));
        kieSession.dispose();
    }



    @Test
    public void test17() {
        System.setProperty("drools.dateformat","yyyy-MM-dd HH:mm");
        KieServices kieServices = KieServices.Factory.get();
        KieContainer kieClasspathContainer = kieServices.getKieClasspathContainer();
        KieSession kieSession = kieClasspathContainer.newKieSession();

        Student student1 = new Student();
        student1.setName("张三");
        student1.setAge(12);

        Student student2 = new Student();
        student2.setName("李四");
        student2.setAge(8);

        Student student3 = new Student();
        student3.setName("王五");
        student3.setAge(22);

//将对象插入Working Memory中
        kieSession.insert(student1);
        kieSession.insert(student2);
        kieSession.insert(student3);

//调用规则文件中的查询
        QueryResults results1 = kieSession.getQueryResults("query_1");
        int size = results1.size();
        System.out.println("size=" + size);
        for (QueryResultsRow row : results1) {
            Student student = (Student) row.get("$student");
            System.out.println(student);
        }

//调用规则文件中的查询
        QueryResults results2 = kieSession.getQueryResults("query_2","王五");
        size = results2.size();
        System.out.println("size=" + size);
        for (QueryResultsRow row : results2) {
            Student student = (Student) row.get("$student");
            System.out.println(student);
        }
//kieSession.fireAllRules();
        kieSession.dispose();
    }
    @Test
    public void test18() {
        System.setProperty("drools.dateformat","yyyy-MM-dd HH:mm");
        KieServices kieServices = KieServices.Factory.get();
        KieContainer kieClasspathContainer = kieServices.getKieClasspathContainer();
        KieSession kieSession = kieClasspathContainer.newKieSession();

        Student student = new Student();
        student.setName("头条：IT人故事会");

        kieSession.insert(student);

        kieSession.fireAllRules(new RuleNameStartsWithAgendaFilter("rule_function_1") );
        kieSession.dispose();
    }


    //测试规则LHS部分 in 和 notin

    @Test
    public void test19() {
        System.setProperty("drools.dateformat","yyyy-MM-dd HH:mm");
        KieServices kieServices = KieServices.Factory.get();
        KieContainer kieClasspathContainer = kieServices.getKieClasspathContainer();
        KieSession kieSession = kieClasspathContainer.newKieSession();
        Student student1 = new Student();
        student1.setAge(61);
        student1.setName("三三");
        kieSession.insert(student1);

//        kieSession.fireAllRules();
        // 指定某种规则开头的规则名称
        kieSession.fireAllRules(new RuleNameStartsWithAgendaFilter("rule_lhs"));
        kieSession.dispose();
    }


    @Test
    public void test20() {
        System.setProperty("drools.dateformat","yyyy-MM-dd HH:mm");
        KieServices kieServices = KieServices.Factory.get();
        KieContainer kieClasspathContainer = kieServices.getKieClasspathContainer();
        KieSession kieSession = kieClasspathContainer.newKieSession();
        Student student1 = new Student();
        student1.setAge(61);
        student1.setName("三三");
        kieSession.insert(student1);

        Student student2 = new Student();
        kieSession.insert(student2);

//        kieSession.fireAllRules();
        // 指定某种规则开头的规则名称
        kieSession.fireAllRules(new RuleNameStartsWithAgendaFilter("rule_lhs"));
        kieSession.dispose();
    }

    @Test
    public void test21() {
        System.setProperty("drools.dateformat","yyyy-MM-dd HH:mm");
        KieServices kieServices = KieServices.Factory.get();
        KieContainer kieClasspathContainer = kieServices.getKieClasspathContainer();
        KieSession kieSession = kieClasspathContainer.newKieSession();
        Student student1 = new Student();
        student1.setAge(15);
        student1.setName("三三");
        kieSession.insert(student1);

//        kieSession.fireAllRules();
        // 指定某种规则开头的规则名称
        kieSession.fireAllRules(new RuleNameStartsWithAgendaFilter("rule_lhs"));
        kieSession.dispose();
    }


    @Test
    public void test22() {
        System.setProperty("drools.dateformat","yyyy-MM-dd HH:mm");
        KieServices kieServices = KieServices.Factory.get();
        KieContainer kieClasspathContainer = kieServices.getKieClasspathContainer();
        KieSession kieSession = kieClasspathContainer.newKieSession();
        Student student1 = new Student();
        student1.setAge(15);
        student1.setName("三三");
        kieSession.insert(student1);

//        kieSession.fireAllRules();
        // 指定某种规则开头的规则名称
        kieSession.fireAllRules(new RuleNameStartsWithAgendaFilter("rule_rhs"));
        kieSession.dispose();
    }

    @Test
    public void test23() throws IOException {
            //通过此URL可以访问到maven仓库中的jar包
            //URL地址构成：http://ip地址:Tomcat端口号/WorkBench工程名/maven2/坐标/版本号/xxx.jar
            String url =
                    "http://127.0.0.1:8080/kie-drools-wb/maven2/com/mytest_space/myproject1/1.0.0/myproject1-1.0.0.jar";

            KieServices kieServices = KieServices.Factory.get();
            //通过Resource资源对象加载jar包
            UrlResource resource = (UrlResource) kieServices.getResources().newUrlResource(url);
            //通过Workbench提供的服务来访问maven仓库中的jar包资源，需要先进行Workbench的认证
            resource.setUsername("kie");
            resource.setPassword("kie");
            resource.setBasicAuthentication("enabled");
            //将资源转换为输入流，通过此输入流可以读取jar包数据
        InputStream inputStream = null;
        try {
            inputStream = resource.getInputStream();
        } catch (IOException e) {
            e.printStackTrace();
        }

        InputStreamReader inputStreamReader = new InputStreamReader(inputStream);
        StringBuffer stringBuffer = new StringBuffer();
        while(inputStreamReader.ready()){
            stringBuffer.append((char)inputStreamReader.read());
        }

        System.out.println(stringBuffer);

        //创建仓库对象，仓库对象中保存Drools的规则信息
            KieRepository repository = kieServices.getRepository();

        Resource resource1 = kieServices.getResources().newInputStreamResource(inputStream);
            //通过输入流读取maven仓库中的jar包数据，包装成KieModule模块添加到仓库中
            KieModule kieModule =
                    repository.addKieModule(kieServices.getResources().newInputStreamResource(inputStream));

            //基于KieModule模块创建容器对象，从容器中可以获取session会话
            KieContainer kieContainer = kieServices.newKieContainer(kieModule.getReleaseId());
            KieSession session = kieContainer.newKieSession();

           Student student = new Student();
           student.setAge(30);
           student.setName("xiaoli");
           session.insert(student);

            session.fireAllRules();
            session.dispose();
        }

}
